#include "utils.h"
#include "format.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

FILE *open_file(const char *filename,const char *mode,FILE *dashhandle,const char *errormessage)
{
	if(dashhandle&&!strcmp(filename,"-")) return dashhandle;

	FILE *fh=fopen(filename,mode);
	if(!fh)
	{
		fprintf(stderr,errormessage,filename);
		exit(10);
	}

	return fh;
}

void check_errors(u_int8_t *bytes,int length,const char *filename,int fixchecksum)
{
	switch(analyze_file(bytes,length))
	{
		case FILE_INCOMPLETE:
			if(filename) fprintf(stderr,"Data in file \"%s\" is incomplete.\n",filename);
			else fprintf(stderr,"Received file is incomplete.\n");
			exit(20);
		break;
		case FILE_FORMAT_INVALID:
		case FILE_SIZE_INVALID:
		case FILE_EMPTY:
			if(filename) fprintf(stderr,"Data in file \"%s\" is corrupted.\n",filename);
			else fprintf(stderr,"Received file is corrupted.\n");
			exit(30);
		break;

		case FILE_CHECKSUM_INVALID:
			if(fixchecksum)
			{
				fprintf(stderr,"Checksum incorrect, fixing.\n");
				fix_checksum(bytes,length);
			}
			else
			{
				if(filename) fprintf(stderr,"Data in file \"%s\" is corrupted.\n",filename);
				else fprintf(stderr,"Received file is corrupted.\n");
				exit(30);
			}
		break;
	}
}

char *describe_file(u_int8_t *bytes,int length)
{
	static char descbuf[256];

	int size=file_size(bytes,length);

	switch(file_format(bytes,length))
	{
		case FORMAT_LEVEL: sprintf(descbuf,"Level named \"%s\", %d bytes.\n",level_name(bytes,length),size); break;
		case FORMAT_REPLAY:  sprintf(descbuf,"Replay record for level \"%s\", %d bytes.\n",level_name(bytes,length),size); break;
		default: sprintf(descbuf,"Unknown file, %d bytes.\n",size); break;
	}

	return descbuf;
}

void write_bigendian_long(u_int32_t val,FILE *fh)
{
	fputc((val>>24)&0xff,fh);
	fputc((val>>16)&0xff,fh);
	fputc((val>>8)&0xff,fh);
	fputc(val&0xff,fh);
}

void die(char *format,...)
{
	va_list va;
	va_start(va,format);
	vfprintf(stderr,format,va);
	va_end(va);
	fprintf(stderr,"\n");
	exit(1);
}
